<template>
  <div class="user-chat-page">
    <a-card class="chat-container" :bordered="false">
      <!-- 聊天室头部 -->
      <div class="chat-header">
        <div class="room-info">
          <h2>聊天室 #{{ roomId }}</h2>
          <div class="time">{{ dayjs(now).format('YYYY-MM-DD HH:mm:ss') }}</div>
        </div>
        <div class="header-actions">
          <a-tooltip title="查询历史消息">
            <a-button type="primary" shape="circle" @click="getHistoryMessage" :loading="loading">
              <template #icon><HistoryOutlined /></template>
            </a-button>
          </a-tooltip>
          <a-badge :count="userVOList.length" :number-style="{ backgroundColor: '#52c41a' }">
            <a-button type="text">
              <template #icon>
                <TeamOutlined />
              </template>
              在线用户
            </a-button>
          </a-badge>
        </div>
      </div>

      <a-row :gutter="16">
        <!-- 聊天消息区域 -->
        <a-col :span="18">
          <div class="chat-messages" ref="chatList" @scroll="handleScroll">
            <!-- 新消息提示 -->
            <div v-if="hasNewMessage && !isAtBottom" class="new-message-alert">
              <a-tooltip
                :title="latestMessage"
                placement="bottom"
                :overlayStyle="{ maxWidth: '300px' }"
              >
                <div class="new-message-button" @click="scrollToBottom">
                  <a-badge :count="newMessageCount" :number-style="{ backgroundColor: '#ff4d4f' }">
                    <div class="new-message-content">
                      <DownOutlined />
                      <span>新消息</span>
                    </div>
                  </a-badge>
                </div>
              </a-tooltip>
            </div>

            <a-list item-layout="horizontal" :data-source="messageList" :loading="loading">
              <template #renderItem="{ item }">
                <a-list-item
                  :class="{
                    'message-item': true,
                    'self-message': isSelf(item),
                    'other-message': !isSelf(item),
                    'new-message': item.isNew,
                  }"
                >
                  <div :class="['message-content-wrapper', isSelf(item) ? 'self' : 'other']">
                    <a-list-item-meta class="meta-position">
                      <template #avatar>
                        <a-tooltip :title="item.userVO?.userName">
                          <a-avatar :src="item.userVO.userAvatar" />
                        </a-tooltip>
                      </template>
                    </a-list-item-meta>
                    <div class="message-content">
                      <div class="message-header">
                        <span class="username">{{ item.userVO?.userName }}</span>
                        <span class="message-time">{{
                          dayjs(item.timestamp).format('HH:mm')
                        }}</span>
                      </div>
                      <div class="message-text">{{ item.content }}</div>
                    </div>
                  </div>
                </a-list-item>
              </template>
            </a-list>
          </div>

          <!-- 输入区域 -->
          <div class="chat-input">
            <a-input-group compact>
              <a-input
                v-model:value="content"
                placeholder="输入消息..."
                :disabled="!websocket?.isConnected"
                @pressEnter="sendMessage"
                style="width: calc(100% - 100px)"
              >
                <template #prefix>
                  <SmileOutlined @click="showEmojiPicker = !showEmojiPicker" />
                </template>
              </a-input>
              <a-button
                type="primary"
                :icon="h(SendOutlined)"
                @click="sendMessage"
                :disabled="!content.trim() || !websocket?.isConnected"
                style="width: 100px"
              >
                发送
              </a-button>
            </a-input-group>

            <!-- 表情选择器 -->
            <div v-if="showEmojiPicker" class="emoji-picker">
              <a-space>
                <a-button v-for="emoji in emojis" :key="emoji" @click="insertEmoji(emoji)">
                  {{ emoji }}
                </a-button>
              </a-space>
            </div>
          </div>
        </a-col>

        <!-- 在线用户列表 -->
        <a-col :span="6">
          <a-card title="在线用户" :bordered="false" class="user-list">
            <a-list item-layout="horizontal" :data-source="userVOList" :loading="loading">
              <template #renderItem="{ item }">
                <a-list-item>
                  <a-list-item-meta>
                    <template #avatar>
                      <a-avatar :src="item.userAvatar" />
                    </template>
                    <template #title>
                      <a @click="router.push(`/user/detail/${item.id}`)">
                        {{ item.userName }}
                      </a>
                    </template>
                    <template #description>
                      <a-tag color="green">在线</a-tag>
                    </template>
                  </a-list-item-meta>
                </a-list-item>
              </template>
            </a-list>
          </a-card>
        </a-col>
      </a-row>
    </a-card>
  </div>
</template>

<script lang="ts" setup>
import UserChatWebSocket from '@/utils/userchatwebsocket.ts'
import { USER_CHAT_MESSAGE_TYPE_ENUM } from '@/constants/room.ts'
import { message } from 'ant-design-vue'
import { h, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { useUserStore } from '@/stores/user.ts'
import {
  SendOutlined,
  TeamOutlined,
  SmileOutlined,
  DownOutlined,
  HistoryOutlined,
} from '@ant-design/icons-vue'
import dayjs from 'dayjs'
import { useRouter } from 'vue-router'
import { userChatMessagePageUsingGet } from '@/api/userChatController.ts'

const router = useRouter()

interface Message {
  content: string
  type?: string
  message?: string
  userVO: API.UserVO
}

const userStore = useUserStore()

// 定义用户列表
const userVOList = ref<API.UserVO[]>([])

// 返回动态时间
const now = ref<Date>(new Date()) // 响应式当前时间

// 每秒更新时间
onMounted(() => {
  const timer = setInterval(() => {
    now.value = new Date()
  }, 1000)
  onUnmounted(() => clearInterval(timer))
})

const messageList = ref<Message[]>([])
const chatList = ref<HTMLElement | null>(null)

// 判断是否是自己的消息
const isSelf = (message: Message) => {
  return message.userVO?.userName === userStore.userInfo?.userName
}

// 查询历史信息
const current = ref(0)
const getHistoryMessage = async () => {
  current.value++
  loading.value = true
  try {
    const res = await userChatMessagePageUsingGet({
      groupId: 1,
      receiverType: 0,
      pageSize: 10,
      current: current.value,
    })
    if (res?.data?.data) {
      // 将历史消息添加到消息列表的开头
      res.data.data?.records.forEach((item: any) =>
        messageList.value.unshift({
          content: item.content,
          userVO: {
            id: item.senderId,
            userName: item.senderName || '',
            userAvatar: item.senderAvatar || '',
          },
          timestamp: item.createTime,
          isNew: false,
        }),
      )
      message.success('已加载历史消息')
    }
  } catch (error) {
    message.error('获取历史消息失败')
  } finally {
    loading.value = false
  }
}

// 滚动到底部
const scrollToBottom = async () => {
  await nextTick()
  if (chatList.value) {
    const listElement = chatList.value
    listElement.scrollTop = listElement.scrollHeight
  }
}

// 定义 props
interface Props {
  roomId: number
}

const props = defineProps<Props>()

// WebSocket 相关逻辑
let websocket: UserChatWebSocket | null

// 新增状态
const isAtBottom = ref(true)
const hasNewMessage = ref(false)
const newMessageCount = ref(0)
const latestMessage = ref('')

// 处理滚动事件
const handleScroll = () => {
  if (!chatList.value) return

  const { scrollTop, scrollHeight, clientHeight } = chatList.value
  const isBottom = scrollHeight - scrollTop - clientHeight < 50

  isAtBottom.value = isBottom
  if (isBottom) {
    hasNewMessage.value = false
    newMessageCount.value = 0
  }
}

// 修改发送消息函数
const content = ref<string>('')

// 新增状态
const loading = ref(false)
const showEmojiPicker = ref(false)
const emojis = ['😊', '😂', '❤️', '👍', '🎉', '🔥', '👏', '🙏']

// 插入表情
const insertEmoji = (emoji: string) => {
  content.value += emoji
  showEmojiPicker.value = false
}

// 修改发送消息函数
const sendMessage = async () => {
  if (!content.value.trim()) return

  loading.value = true
  try {
    // 添加自己的消息到列表
    const newMessage = {
      content: content.value,
      userVO: {
        userName: userStore.userInfo?.userName || '',
        userAvatar: userStore.userInfo?.userAvatar || '',
        id: userStore.userInfo?.id,
      },
      timestamp: new Date().toISOString(),
      isNew: true,
    }
    messageList.value.push(newMessage)

    // 滚动到底部
    await nextTick()
    scrollToBottom()

    // 发送 WebSocket 消息
    if (!websocket) {
      websocket = new UserChatWebSocket(props.roomId)
      websocket.connect()
    }
    websocket?.sendMessage({
      type: USER_CHAT_MESSAGE_TYPE_ENUM.SEND_MESSAGE,
      content: content.value,
    })
    content.value = ''
  } catch (err: unknown) {
    const error = err as Error
    message.error(error.message || '发送消息失败')
  } finally {
    loading.value = false
  }
}

// 修改 WebSocket 消息处理
const initWebSocket = () => {
  if (websocket) {
    websocket.disconnect()
  }
  websocket = new UserChatWebSocket(props.roomId)
  websocket.connect()

  // 监听消息
  websocket.on(USER_CHAT_MESSAGE_TYPE_ENUM.INFO, (msg) => {
    message.info(msg.message)
    if (msg.userVOList) {
      userVOList.value = msg.userVOList
    }
  })
  websocket.on(USER_CHAT_MESSAGE_TYPE_ENUM.ERROR, (msg) => {
    message.error(msg.message)
  })
  websocket.on(USER_CHAT_MESSAGE_TYPE_ENUM.SEND_MESSAGE, (msg) => {
    const newMsg = {
      ...msg,
      isNew: true,
      timestamp: new Date().toISOString(),
    }
    messageList.value.push(newMsg)

    // 更新最新消息内容
    latestMessage.value = `${msg.userVO?.userName}: ${msg.content}`

    // 如果不在底部，显示新消息提示
    if (!isAtBottom.value) {
      hasNewMessage.value = true
      newMessageCount.value++
    } else {
      // 如果在底部，自动滚动
      scrollToBottom()
    }
  })
}

// 生命周期钩子
onMounted(async () => {
  await getHistoryMessage() // 先获取历史消息
  initWebSocket() // 再初始化 WebSocket
})
onUnmounted(() => {
  if (websocket) {
    websocket.disconnect()
  }
})
</script>

<style scoped>
.user-chat-page {
  padding: 16px;
  height: calc(100vh - 32px);
  background-color: #f0f2f5;
  display: flex;
  flex-direction: column;
}

.chat-container {
  height: 90%;
  display: flex;
  flex-direction: column;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #f0f0f0;
  background-color: #fff;
  border-radius: 8px 8px 0 0;
}

.room-info h2 {
  margin: 0;
  color: #1890ff;
  font-size: 18px;
}

.time {
  color: #999;
  font-size: 13px;
  margin-top: 4px;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  background-color: #fafafa;
  height: calc(100vh - 220px);
  min-height: 300px;
  display: flex;
  flex-direction: column;
}

.message-item {
  margin-bottom: 12px;
  width: 100%;
}

.message-content-wrapper {
  display: flex;
  align-items: flex-start;
  max-width: 75%;
  gap: 8px;
}

.message-content-wrapper.self {
  flex-direction: row-reverse;
  margin-left: auto;
}

.message-content {
  background-color: #f5f5f5;
  padding: 8px 12px;
  border-radius: 12px;
  position: relative;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  min-width: 60px;
}

.message-content-wrapper.self .message-content {
  background-color: #e6f7ff;
}

.message-header {
  display: flex;
  align-items: center;
  margin-bottom: 4px;
  gap: 8px;
}

.username {
  font-weight: 500;
  font-size: 13px;
  color: #666;
}

.message-time {
  font-size: 12px;
  color: #999;
}

.message-text {
  word-break: break-word;
  line-height: 1.5;
  font-size: 14px;
  color: #333;
}

.chat-input {
  position: relative;
  padding: 12px 16px;
  background-color: #fff;
  border-top: 1px solid #f0f0f0;
  border-radius: 0 0 8px 8px;
}

.emoji-picker {
  position: absolute;
  bottom: 100%;
  left: 16px;
  background-color: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  padding: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  z-index: 1000;
}

.user-list {
  height: 100%;
  overflow-y: auto;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

:deep(.ant-list-item-meta) {
  align-items: center;
  padding: 8px 0;
}

:deep(.ant-avatar) {
  cursor: pointer;
  transition: transform 0.3s;
}

:deep(.ant-avatar:hover) {
  transform: scale(1.1);
}

:deep(.ant-input-group) {
  display: flex;
  align-items: center;
}

:deep(.ant-input) {
  border-radius: 4px 0 0 4px;
}

:deep(.ant-btn) {
  border-radius: 0 4px 4px 0;
}

:deep(.ant-list-item) {
  padding: 0 !important;
  border-bottom: none !important;
}

:deep(.ant-list-item-meta) {
  margin-bottom: 0 !important;
}

:deep(.ant-avatar) {
  width: 40px;
  height: 40px;
  border: 2px solid #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.new-message-alert {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  cursor: pointer;
  transition: all 0.3s;
  background-color: #fff;
  border-radius: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  padding: 4px 12px;
}

.new-message-button {
  display: flex;
  align-items: center;
  gap: 4px;
  color: #ff4d4f;
  font-size: 14px;
  padding: 4px 8px;
}

.new-message-content {
  display: flex;
  align-items: center;
  gap: 4px;
}

.new-message-button:hover {
  color: #ff7875;
}

.message-item.new-message {
  animation: highlight 2s ease-out;
}

@keyframes highlight {
  0% {
    background-color: rgba(255, 77, 79, 0.1);
  }
  100% {
    background-color: transparent;
  }
}

:deep(.ant-badge-count) {
  box-shadow: 0 0 0 1px #fff;
}

:deep(.ant-tooltip-inner) {
  max-width: 300px;
  word-break: break-word;
  white-space: pre-wrap;
  text-align: left;
  padding: 8px 12px;
  font-size: 13px;
  line-height: 1.5;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

:deep(.ant-btn-circle) {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}
</style>
